﻿using Microsoft.AspNet.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.Configuration;
using System.Diagnostics;
using Core.Context;
using Front.Core.Dtos;
using Core.IProxyServices;
using Core.Mappers;

namespace ProxyServices
{
    public class UserStoreProxyService : ClientBase<IUserStoreService>, IUserStoreService, IUserStore<UserDto, string>, IUserPasswordStore<UserDto, string>, IUserRoleStore<UserDto, string>, IUserLoginStore<UserDto>
    {
        public UserStoreProxyService(IFrontConfig settings)
            : base(new BasicHttpBinding(), new EndpointAddress(settings.WcfUrl + @"/UserStore.svc"))
        {            
        }

        public async Task CreateAsync(UserDto user)
        {
            string id = await this.CreateAndGetIdAsync(user);
            user.Id = id;
        }

        public async Task<string> CreateAndGetIdAsync(UserDto user)
        {
            return await base.Channel.CreateAndGetIdAsync(user);
        }

        public async Task DeleteAsync(UserDto user)
        {
            await base.Channel.DeleteAsync(user);
        }

        public async Task<UserDto> FindByIdAsync(string userId)
        {
            return await base.Channel.FindByIdAsync(userId);
        }

        public async Task<UserDto> FindByNameAsync(string userName)
        {                  
            var result = await base.Channel.FindByNameAsync(userName);
            return result;
        }

        public async Task UpdateAsync(UserDto user)
        {
            await base.Channel.UpdateAsync(user);
        }

        public async Task<string> GetPasswordHashAsync(UserDto user)
        {
            var result = await base.Channel.GetPasswordHashAsync(user);
            return result;
        }

        public async Task<bool> HasPasswordAsync(UserDto user)
        {
            return await base.Channel.HasPasswordAsync(user);
        }

        public async Task SetPasswordHashAsync(UserDto user, string passwordHash)
        {
            await base.Channel.SetPasswordHashAsync(user, passwordHash);
            user.PasswordHash = passwordHash;
        }

        public async Task<string> GetSecurityStampAsync(UserDto user)
        {
            return await base.Channel.GetSecurityStampAsync(user);
        }

        public async Task SetSecurityStampAsync(UserDto user, string stamp)
        {
            await base.Channel.SetSecurityStampAsync(user, stamp);
            user.SecurityStamp = stamp;
        }

        public async Task AddToRoleAsync(UserDto user, string roleName)
        {
            await base.Channel.AddToRoleAsync(user, roleName);
        }

        public async Task<IList<string>> GetRolesAsync(UserDto user)        
        {
            var result = await base.Channel.GetRolesAsync(user);
            return result;
        }

        public async Task<bool> IsInRoleAsync(UserDto user, string roleName)
        {
            return await base.Channel.IsInRoleAsync(user, roleName);
        }

        public async Task RemoveFromRoleAsync(UserDto user, string roleName)
        {
            await base.Channel.RemoveFromRoleAsync(user, roleName);
        }

        //map before call
        public async Task AddLoginAsync(UserDto user, UserLoginInfo login)
        {
            UserLoginInfoTo loginTo = login.Map<UserLoginInfoTo>();
            await this.AddLoginAsync(user, loginTo);
        }

        public async Task<UserDto> FindAsync(UserLoginInfo login)
        {
            UserLoginInfoTo loginTo = login.Map<UserLoginInfoTo>();
            return await this.FindAsync(loginTo);
        }

        public async Task<IList<UserLoginInfo>> GetLoginsAsync(UserDto user)
        {
            var list = await this.GetLoginsAsyncAsTos(user);
            return list.Map<UserLoginInfoTo, UserLoginInfo>();
        }

        public async Task RemoveLoginAsync(UserDto user, UserLoginInfo login)
        {
            UserLoginInfoTo loginTo = login.Map<UserLoginInfoTo>();
            await this.RemoveLoginAsync(user, loginTo);
        }

        //proxy calls
        public async Task AddLoginAsync(UserDto user, UserLoginInfoTo login)
        {           
            await base.Channel.AddLoginAsync(user, login);
        }

        public async Task<UserDto> FindAsync(UserLoginInfoTo login)
        {
            return await base.Channel.FindAsync(login);
        }

        public async Task<IList<UserLoginInfoTo>> GetLoginsAsyncAsTos(UserDto user)
        {
            return await base.Channel.GetLoginsAsyncAsTos(user);
        }

        public async Task RemoveLoginAsync(UserDto user, UserLoginInfoTo login)
        {            
            await base.Channel.RemoveLoginAsync(user, login);
        }
    }
}